package com.sihai.core.beans;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.springframework.beans.BeansException;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.util.ReflectionUtils;

import com.sihai.core.AppSettings;
import com.sihai.core.utils.BeanUtils;

public class PropertyAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

	private SimpleTypeConverter typeConverter = new SimpleTypeConverter();

	@Override
	public boolean postProcessAfterInstantiation(final Object bean, String beanName) throws BeansException {

		ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
			public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
				Property cfg = field.getAnnotation(Property.class);
				if (cfg == null) {
					return;
				}

				if (Modifier.isStatic(field.getModifiers())) {
					throw new IllegalStateException("@Property annotation is not supported on static fields");
				}

				//如果开发者没有设置@Property的 value，则使用变量域的名称作为键查找配置资源
				String key = cfg.value().length() <= 0 ? field.getName() : cfg.value();
				String value = AppSettings.getSetting(key);

				if (value != null) {
					//转换配置值成其它非String类型
					Object _value = typeConverter.convertIfNecessary(value, field.getType());
					//并且转换后的配置值注入其中
					ReflectionUtils.makeAccessible(field);
					field.set(bean, _value);
					try {
						BeanUtils.setFieldValue(bean, field, _value);
					} catch (NoSuchFieldException e) {
						throw new BeanCreationException("set field due to error", e);
					}
				}
			}

		});

		//通常情况下返回true即可
		return true;
	}

}
